<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>RTC Post Data Test</title>
    <script src="/packages/libs/ofa/ofa.js" type="module"></script>
  </head>
  <body>
    <script type="module">
      import { test } from "/ok-test/main.js";
      import { createUser } from "/packages/user/main.js";

      await test("RTC Connection and Post Data Test", async () => {
        // 创建两个用户
        const user1 = await createUser({ user: "test-rtc-user1" });
        const user2 = await createUser({ user: "test-rtc-user2" });

        user1._ignoreCert = true;
        user2._ignoreCert = true;

        const serverUrl = "ws://localhost:18290";

        // 保证user2连上服务器
        await user2.connectServer(serverUrl);

        // user2监听获取数据的事件
        let receivedData = null;
        let receivedFromUserId = null;
        let receivedFromUserSessionId = null;
        let receivedChannel = null;
        let receivedServerUndefined = false;

        const receiveDataPromise = new Promise((resolve) => {
          user2.addEventListener("receive-data", (e) => {
            const { fromUserId, fromUserSessionId, data, server, channel } =
              e.detail;

            // 通过 RTC 转发，server 字段应不存在
            receivedServerUndefined = server === undefined;

            receivedData = data;
            receivedFromUserId = fromUserId;
            receivedFromUserSessionId = fromUserSessionId;
            receivedChannel = channel;

            resolve({ fromUserId, fromUserSessionId, data, server, channel });
          });
        });

        // 保证user1也连上服务器
        await user1.connectServer(serverUrl);

        // 直接连接 user2
        let remoteUser2;
        try {
          remoteUser2 = await user1.connectUser({ userId: user2.userId });

          // 初始化RTC连接，完成后就会使用点对点进行数据通信
          await remoteUser2.initRTC();
        } catch (error) {
          console.log("连接用户或rtc初始化失败:", error);
          throw error;
        }

        // 发送数据给对方
        const testData = {
          val: "hello user2 via RTC",
          timestamp: Date.now(),
        };

        // 通过用户1生成的远端用户2实例发送数据到用户2上
        remoteUser2.post(testData);

        // 等待接收数据
        await receiveDataPromise;

        // 验证接收到的数据
        const isCorrectSender = receivedFromUserId === user1.userId;
        const isCorrectSession = receivedFromUserSessionId === user1.sessionId;
        const isCorrectData =
          JSON.stringify(receivedData) === JSON.stringify(testData);
        const isServerUndefined = receivedServerUndefined;

        return {
          assert:
            isCorrectSender &&
            isCorrectSession &&
            isCorrectData &&
            isServerUndefined,
          content: {
            message: "RTC连接后post数据测试成功",
            sentData: testData,
            receivedData: receivedData,
            fromUserId: receivedFromUserId,
            fromUserSessionId: receivedFromUserSessionId,
            isCorrectSender,
            isCorrectSession,
            isCorrectData,
            isServerUndefined,
          },
        };
      });

      await test("RTC Connection Fallback to Server Test", async () => {
        // 创建两个用户
        const user1 = await createUser({ user: "test-rtc-fallback-user1" });
        const user2 = await createUser({ user: "test-rtc-fallback-user2" });

        user1._ignoreCert = true;
        user2._ignoreCert = true;

        const serverUrl = "ws://localhost:18290";

        // 保证user2连上服务器
        await user2.connectServer(serverUrl);

        // user2监听获取数据的事件
        let receivedData = null;
        let receivedFromUserId = null;
        let receivedServerExists = false;

        const receiveDataPromise = new Promise((resolve) => {
          user2.addEventListener("receive-data", (e) => {
            const { fromUserId, data, server } = e.detail;

            // 通过服务器转发，server 字段应存在
            receivedServerExists = server !== undefined;

            receivedData = data;
            receivedFromUserId = fromUserId;

            resolve({ fromUserId, data, server });
          });
        });

        // 保证user1也连上服务器
        await user1.connectServer(serverUrl);

        // 直接连接 user2
        let remoteUser2;
        try {
          remoteUser2 = await user1.connectUser({ userId: user2.userId });

          // 不初始化RTC连接，直接发送数据，应该会降级到服务器转发
        } catch (error) {
          console.log("连接用户失败:", error);
          throw error;
        }

        // 发送数据给对方
        const testData = {
          val: "hello user2 via server fallback",
          timestamp: Date.now(),
        };

        // 通过用户1生成的远端用户2实例发送数据到用户2上
        remoteUser2.post(testData);

        // 等待接收数据
        await receiveDataPromise;

        // 验证接收到的数据
        const isCorrectSender = receivedFromUserId === user1.userId;
        const isCorrectData =
          JSON.stringify(receivedData) === JSON.stringify(testData);
        const isServerExists = receivedServerExists;

        return {
          assert: isCorrectSender && isCorrectData && isServerExists,
          content: {
            message: "RTC连接失败降级到服务器转发测试成功",
            sentData: testData,
            receivedData: receivedData,
            fromUserId: receivedFromUserId,
            isCorrectSender,
            isCorrectData,
            isServerExists,
          },
        };
      });

      await test("Simulate Sudden P2P Disconnection", async () => {
        // 创建两个用户
        const user1 = await createUser({ user: "test-rtc-reconnect-user1" });
        const user2 = await createUser({ user: "test-rtc-reconnect-user2" });

        user1._ignoreCert = true; // _ignoreCert 用于忽略 rtc 的配对的设备判断行为，仅用于测试环境
        user2._ignoreCert = true;

        await user1.connectAllServers();
        await user2.connectAllServers();

        // 直接连接 user2
        let remoteUser2;
        try {
          // remoteUser2 = await user1.connectUser({ userId: user2.userId });
          remoteUser2 = await user1.connectUser(user2.userId);

          // 初始化RTC连接，完成后就会使用点对点进行数据通信
          await remoteUser2.initRTC();
        } catch (error) {
          console.log("连接用户或rtc初始化失败:", error);
          throw error;
        }

        // user2监听获取数据的事件
        let receivedCount = 0;
        let firstReceivedData = null;
        let firstIsServer = false;
        let firstReceivedServer = null;
        let secondReceivedData = null;
        let secondIsServer = false;
        let secondReceivedChannel = null;
        let thirdReceivedData = null;
        let thirdIsServer = false;
        let thirdReceivedChannel = null;

        const receiveDataPromises = [
          new Promise((resolve) => {
            user2.addEventListener("receive-data", (e) => {
              if (receivedCount === 0) {
                const { data, server, channel } = e.detail;
                firstReceivedData = data;
                firstIsServer = !!server;
                firstReceivedServer = server;
                resolve();
                Promise.resolve().then(() => {
                  receivedCount++;
                });
              }
            });
          }),
          new Promise((resolve) => {
            user2.addEventListener("receive-data", (e) => {
              if (receivedCount === 1) {
                const { data, server, channel } = e.detail;
                secondReceivedData = data;
                secondIsServer = !!server;
                secondReceivedChannel = channel;
                resolve();
                Promise.resolve().then(() => {
                  receivedCount++;
                });
              }
            });
          }),
          new Promise((resolve) => {
            user2.addEventListener("receive-data", (e) => {
              if (receivedCount === 2) {
                const { data, server, channel } = e.detail;
                thirdReceivedData = data;
                thirdIsServer = !!server;
                thirdReceivedChannel = channel;
                resolve();
                Promise.resolve().then(() => {
                  receivedCount++;
                });
              }
            });
          }),
        ];

        // 发送第一条数据，应该通过RTC传输
        const testData1 = {
          val: "hello user2 via RTC",
          timestamp: Date.now(),
          type: "first",
        };

        remoteUser2.post(testData1);

        // 等待第一条数据接收完成
        await receiveDataPromises[0];

        // 模拟RTC连接断开
        remoteUser2._rtcConnections[0].close();

        // 等待一小段时间确保连接关闭
        await new Promise((resolve) => setTimeout(resolve, 200));

        // 发送第二条数据，此时RTC已断开，应该通过服务器转发
        const testData2 = {
          val: "hello user2 via server fallback",
          timestamp: Date.now(),
          type: "second",
        };

        remoteUser2.post(testData2);

        // 等待第二条数据接收完成
        await receiveDataPromises[1];

        // 发送第三条数据，应该有channel
        const testData3 = {
          val: "hello user2 with channel",
          timestamp: Date.now(),
          type: "third",
        };

        remoteUser2.post(testData3);

        // 等待第三条数据接收完成
        await receiveDataPromises[2];

        // 验证结果
        const isFirstDataCorrect =
          JSON.stringify(firstReceivedData) === JSON.stringify(testData1);
        const isSecondDataCorrect =
          JSON.stringify(secondReceivedData) === JSON.stringify(testData2);
        const isThirdDataCorrect =
          JSON.stringify(thirdReceivedData) === JSON.stringify(testData3);
        const isFirstViaRTC = !firstIsServer; // 第一次应该通过RTC，没有server字段
        const isSecondViaServer = !!secondIsServer; // 第二次应该通过服务器，有server字段
        const isThirdWithChannel = !thirdReceivedChannel; // 第三次应该有channel

        return {
          assert:
            isFirstDataCorrect &&
            isSecondDataCorrect &&
            isThirdDataCorrect &&
            isFirstViaRTC &&
            isSecondViaServer &&
            isThirdWithChannel,
          content: {
            message: "RTC重连测试成功",
            isFirstDataCorrect,
            isSecondDataCorrect,
            isThirdDataCorrect,
            isFirstViaRTC,
            isSecondViaServer,
            isThirdWithChannel,
            firstReceivedData,
            secondReceivedData,
            thirdReceivedData,
            firstReceivedServer: !!firstReceivedServer,
            secondReceivedChannel: !!secondReceivedChannel,
            thirdReceivedChannel: !!thirdReceivedChannel,
          },
        };
      });
    </script>
  </body>
</html>
